package wht.jly.forum.utils.validatecode.image;

import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import wht.jly.forum.utils.validatecode.properties.ImageValidateCodeProperties;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 图形验证码生成器的默认实现
 * <p>
 * 如果用户需要自定义验证码生成方式，只需要
 * 1. 继承ValidateCodeGenerator接口，并实现其方法
 * 2. 向容器中注入你的实现类，并标记bean名字为 "imageCodeGenerator"，以覆盖此默认实现
 *
 * @author lanyangji
 * @date 2019/2/19 20:35
 */
public class ImageValidateCodeGenerator {

    private ImageValidateCodeProperties imageValidateCodeProperties;

    /**
     * 生成验证码 ImageCode 对象
     *
     * @param request ServletWebRequest包装后的request对象
     * @return
     */
    public ImageValidateCode generate(ServletWebRequest request) {
        /**
         * 从请求中取出图形验证码的宽度
         */
        int width = ServletRequestUtils.getIntParameter(request.getRequest(), "imageCodeWidth", imageValidateCodeProperties.getWidth());
        /**
         * 从请求中取出图形验证码的高度
         */
        int height = ServletRequestUtils.getIntParameter(request.getRequest(), "imageCodeHeight", imageValidateCodeProperties.getHeight());

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics g = image.getGraphics();

        // 随机数对象
        Random random = new Random();

        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Times New Roman", Font.ITALIC, 20));
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(12);
            int y1 = random.nextInt(12);
            g.drawLine(x, y, x1, y1);
        }

        String sRand = "";
        for (int i = 0; i < imageValidateCodeProperties.getLength(); i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            g.drawString(rand, 13 * i + 6, 16);
        }

        g.dispose();

        return new ImageValidateCode(sRand, imageValidateCodeProperties.getExpireIn(), image);
    }

    /**
     * 生成随机背景条纹
     *
     * @param fc
     * @param bc
     * @return
     */
    private Color getRandColor(int fc, int bc) {
        int maxRGB = 255;
        Random random = new Random();
        if (fc > maxRGB) {
            fc = maxRGB;
        }
        if (bc > maxRGB) {
            bc = maxRGB;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    public ImageValidateCodeProperties getImageValidateCodeProperties() {
        return imageValidateCodeProperties;
    }

    public void setImageValidateCodeProperties(ImageValidateCodeProperties imageValidateCodeProperties) {
        this.imageValidateCodeProperties = imageValidateCodeProperties;
    }

    public ImageValidateCodeGenerator() {
    }

    public ImageValidateCodeGenerator(ImageValidateCodeProperties imageValidateCodeProperties) {
        this.imageValidateCodeProperties = imageValidateCodeProperties;
    }
}
